import { reactive, ref } from 'vue'
import store from '@/store/index'
type PullOptions<T> = {
  loading: boolean
  finished: boolean
  refreshing: boolean
  finishedText?: string
  rows: T[]
  totalRows: number
  totalPage: number
  pageSize: number
  pageNo: number
  noData: boolean
}

type Fn = any

/**
 * @param url 请求数据列表的store里面的方法
 * @param queryModel 除了pagesize pageNo 之外的 参数
 * @param finishedText 加载完之后没有更多的 文字描述
 * @param beforeRequestCallback 请求之前的回调
 * @param afterRefreshRequestCallback 刷新请求之后的回调
 * @param afterLoadMoreRequestCallback 加载更多请求之后的回调
 * @param asyncRefreshRequestCallback 与刷新同时进行的回调
 * @param successBuildData 请求成功后 对数据进行重构
 */
const usePullDownUp = <T>(obj: {
  url: any
  queryModel: any
  finishedText?: string
  beforeRequestCallback?: Fn
  afterRefreshRequestCallback?: Fn
  afterLoadMoreRequestCallback?: Fn
  asyncRefreshRequestCallback?: Fn
  successBuildData?: Fn
}): any => {
  const {
    queryModel,
    finishedText,
    beforeRequestCallback,
    afterRefreshRequestCallback,
    afterLoadMoreRequestCallback,
    asyncRefreshRequestCallback,
    successBuildData
  } = obj
  const pullOptions = reactive<PullOptions<T>>({
    rows: [],
    loading: false,
    finished: false,
    refreshing: true,
    noData: true,
    finishedText: '没有更多数据~~~',
    totalRows: 0,
    totalPage: 0,
    pageSize: 10,
    pageNo: 1
  })

  // 单独搜索刷新
  const isSingleSearchRefresh = ref<boolean>(false)

  finishedText && (pullOptions.finishedText = finishedText)

  let queryParams = reactive<any>({ pageSize: pullOptions.pageSize, pageNo: pullOptions.pageNo })

  queryParams = Object.assign(queryParams, queryModel)

  const loadData = async (): Promise<void> => {
    handleQueryData()
  }

  const pullDownRefresh = async () => {
    // 清空列表数据
    pullOptions.pageNo = 1
    pullOptions.finished = false
    pullOptions.loading = true
  }

  const handleQueryData = async (): Promise<void> => {
    // 请求之前的回调
    beforeRequestCallback && typeof beforeRequestCallback === 'function' && (await beforeRequestCallback())

    // 同步刷新的回调
    pullOptions.refreshing &&
      asyncRefreshRequestCallback &&
      typeof asyncRefreshRequestCallback === 'function' &&
      (await asyncRefreshRequestCallback())
    const result = await store.dispatch(obj.url.value, queryParams)
    if (result) {
      if (pullOptions.refreshing || isSingleSearchRefresh.value) {
        // 如果是刷新
        pullOptions.rows = []
        pullOptions.refreshing = false

        // 刷新之后的回调
        beforeRequestCallback && typeof afterRefreshRequestCallback === 'function' && afterRefreshRequestCallback()
      } else {
        // 加载更多之后的回调
        afterLoadMoreRequestCallback &&
          typeof afterLoadMoreRequestCallback === 'function' &&
          afterLoadMoreRequestCallback()
      }
      isSingleSearchRefresh.value = false // 关闭单独刷新
      const rows: any[] = result.rows
      if (successBuildData && typeof successBuildData === 'function') {
        successBuildData(rows)
      }
      pullOptions.rows = pullOptions.rows.concat(rows)
      pullOptions.loading = false
      const { pageSize, pageNo } = queryParams
      if (pageSize * pageNo >= result.totalRows) {
        pullOptions.finished = true
      } else {
        queryParams.pageNo += 1
      }

      if (pullOptions.rows.length < 1) {
        pullOptions.noData = true
      } else {
        pullOptions.noData = false
      }
    }
  }

  // 刷新数据
  const onRefresh = (data: any): void => {
    queryParams = Object.assign(queryParams, data, {
      pageNo: 1
    })
    isSingleSearchRefresh.value = true
    loadData()
  }

  return {
    pullOptions,
    loadData,
    pullDownRefresh,
    handleQueryData,
    queryParams,
    onRefresh
  }
}

export default usePullDownUp
